#pragma once

#include "../base/types.h"
#include "avx.h"


OPEN_JLIB_NS


template<typename T = u8v16>
inline T avx_vextsign128 (u64 msk) noexcept {
  auto l = x86_pdep<u64>(msk, 0x8080808080808080UL);
  auto h = x86_pdep<u64>(msk >> 8, 0x8080808080808080UL);
  return avx_cast<T>(u64v2{l, h});
}


template<typename T = u8v32>
inline T avx_vextsign256 (u64 msk) noexcept {
  auto ll = x86_pdep<u64>(msk, 0x8080808080808080UL);
  auto lh = x86_pdep<u64>(msk >> 8, 0x8080808080808080UL);
  auto hl = x86_pdep<u64>(msk >> 16, 0x8080808080808080UL);
  auto hh = x86_pdep<u64>(msk >> 24, 0x8080808080808080UL);
  return avx_cast<T>(u64v4{ll, lh, hl, hh});
}


template<typename T = s8v16>
inline T avx_vldstr (const void *src, u64 len) noexcept {
  auto raw = avx_vpxor<s8v16>(s8v16{}, s8v16{});
  auto msk = avx_vextsign128<s8v16>((1UL << len) - 1);
  return avx_vpblendvb<s8v16>(raw, src, msk);
}


template<typename T = s8v16>
inline void avx_vststr (void *dst, T str, u64 len) noexcept {
  auto msk = avx_vextsign128<s8v16>((1UL << len) - 1);
  avx_vmaskmovdqu(dst, str, msk);
}


CLOSE_JLIB_NS
